package com.dataex.dbtool;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 时间工具类
 * 
 * @author haoxw
 * 
 */
public class DateUtil {

	public static enum DateTimeFormat{
		
		yyyymd(1, "yyyy-M-d"), //1997-3-4
		yyyymmdd_hhmmss(2,"yyyy-MM-dd HH:mm:ss"), //1997-03-04 13:30:12
		yyyymd_hm_ampm(3,"yyyy-MM-dd h:m a"),//1997-3-4 1:30 PM
		yyyymd_hm(4,"yyyy-MM-dd h:m"),//1997-3-4 13:30
		yymd(5,"yy-M-d"),//97-3-4
		mdyy(6,"M-d-yy"),//3-4-97
		mmddyy(7,"MM-dd-yy"),//03-04-97
		md(8,"M-d"),//3-4
		yyyymd_chinese(9,"yyyy'年'M'月'dd'日'"),//一九九七年三月四日
		yyyym_chinese(10,"yyyy'年'M'月'"),//一九九七年三月
		md_chinese(11,"M'月'd'日'"),//三月四日
		yyyymd_ymdchinese(12,"yyyy年M月d日"),//1997年3月4日
		yyyym_ymdchinese(13,"yyyy年M月"),//1997年3月
		md_ymdchinese(14,"M月d日"),//3月4日
		week_chinese(15,"'星期'W"),//星期二
		weeknum_chinese(16,"W"),//二
		d_menu(17,"d-MMM"),//4-Mar
		dmyy_menu(18,"d-MMM-yy"),//4-Mar-97
		ddmyy_menu(19,"dd-MMM-dd"),//04-Mar-97
		myy_menu(20,"MMM-yy"),//Mar-97
		myy_menu_fullmonth(21,"MMMM-yy");//March-97
		public int index;
		public String format;
		DateTimeFormat(int index, String format){
			this.index = index;
			this.format = format;
		}
	};

	public static enum TimeFormat {
		/**
		 * 13:30
		 */
		hhmm(1, "HH:mm"), // 13:30
		hm_ampm(2, "h:mm a"), // 1:30 PM 
		hhmmss(3, "HH:mm:ss"), // 13:30:00 
		hms_ampm(4, "h:mm:ss a"), // 1:30:00 PM 
		hhmm_hmsChinese(5, "HH时mm分"), // 13时30分 
		hhmmss_hmsChinese(6, "HH时mm分ss秒"), //13时30分00秒
		hhmm_ampm_hmsChinese(7, "ah时m分"), // 下午1时30分 
		hhmmss_ampm_hmsChinese(8, "ah时m分ss秒"), // 下午1时30分00秒 
		hhmm_chinese(9, "HH时mm分"), // 十三时三十分 
		hhmmss_ampm_chinese(10, "aHH时mm分"); //下午一时三十分 

		public int index;
		public String format;
		TimeFormat(int index, String format){
			this.index = index;
			this.format = format;
		}
		
	}
	
	
	private static final Logger log = LoggerFactory.getLogger(DateUtil.class);

	public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 获取相隔interval天的时间 并返回pattern类型的string
	 * 
	 * @param interval
	 * @param starttime
	 * @param pattern
	 * @return
	 */
	public static String getDate(String interval, Date starttime, String pattern) {
		Calendar temp = Calendar.getInstance(TimeZone.getDefault());
		temp.setTime(starttime);
		temp.add(temp.DATE, Integer.parseInt(interval));
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(temp.getTime());
	}

	/**
	 * 将字符串类型转换为时间类型
	 * 
	 * @param str (2014-7-7 23:23:23)
	 * @return
	 */
	public static Date str2Date(String str) {
		Date d = null;
		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_PATTERN);
		try {
			d = sdf.parse(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return d;
	}


	/**
	 * 将字符串按照pattern类型转换为时间类型
	 * 
	 * @param str (2014-7-7 23:23:23)
	 * @param pattern
	 * @return
	 */
	public static Date str2Date(String str, String pattern) {
		Date d = null;
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		try {
			d = sdf.parse(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return d;
	}
	
	/**
	 * 将时间格式化
	 * 
	 * @return
	 */
	public static Date DatePattern(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_PATTERN);
		try {
			String dd = sdf.format(date);
			date = str2Date(dd);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 将long转成时间格式
	 * 
	 * @param datelong
	 * @param format
	 * @return
	 */
	public static String long2date(long datelong, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date date = new Date();
		date.setTime(datelong);
		return sdf.format(date);
	}

	/**
	 * 将时间格式化
	 */
	public static Date DatePattern(Date date, String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		try {
			String dd = sdf.format(date);
			date = str2Date(dd, pattern);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 将date转换成默认时间格式的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String date2Str(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_PATTERN);
		return sdf.format(date);
	}

	/**
	 * 将date转换成format格式的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String date2Str(Date date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}
	
	public static String date2StrByEnum(Date date, DateTimeFormat fmt ){
		SimpleDateFormat sdf = new SimpleDateFormat(fmt.format, Locale.US);
		String dateD = sdf.format(date);
		if ( fmt.index == DateTimeFormat.yyyymd_hm_ampm.index ){
			dateD = dateD.replace("上午", "AM");
			dateD = dateD.replace("下午", "PM");
			
		}
		else if ( fmt.index == DateTimeFormat.md_chinese.index ){
			dateD = ImpStringUtil.numToChineseNum(dateD, -1, -1);
		}
		else if ( fmt.index == DateTimeFormat.week_chinese.index || fmt.index == DateTimeFormat.weeknum_chinese.index ){
			dateD = ImpStringUtil.numBitToChineseBit(dateD, -1, -1);
		}
		else if (fmt.index == DateTimeFormat.yyyym_chinese.index || fmt.index == DateTimeFormat.yyyymd_chinese.index ){
			dateD = ImpStringUtil.numBitToChineseBit(dateD, 0, 3);
			dateD = ImpStringUtil.numToChineseNum(dateD, 4, -1);
		}
		return dateD;
	}
	
	public static String date2TimeStrByEnum(Date date, TimeFormat fmt ){
		SimpleDateFormat sdf = new SimpleDateFormat(fmt.format, Locale.US);
		String dateD = sdf.format(date);
		if ( fmt.index == TimeFormat.hhmm_ampm_hmsChinese.index || fmt.index == TimeFormat.hhmmss_ampm_hmsChinese.index
				|| fmt.index == TimeFormat.hhmmss_ampm_chinese.index ){
			dateD = dateD.replace("AM", "上午");
			dateD = dateD.replace("PM", "下午");
		}
		
		if ( fmt.index == TimeFormat.hhmm_chinese.index || fmt.index == TimeFormat.hhmmss_ampm_chinese.index ){
			dateD = ImpStringUtil.numToChineseNum(dateD, -1, -1);
		}
		return dateD;
	}
	
	/**
	 * 获取昨天
	 * 
	 * @param date
	 * @return
	 * @throws Exception
	 */
	public static Date getLastDate(Date date) {
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		calendar.setTime(date);

		calendar.add(calendar.DATE, -1);

		return str2Date(date2Str(calendar.getTime()));
	}

	/**
	 * 获取昨天
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 * @throws Exception
	 */
	public static String getLastDate(Date date, String pattern) {
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		calendar.setTime(date);
		calendar.add(calendar.DATE, -1);
		return date2Str(calendar.getTime(), pattern);
	}

	/**
	 * 获取上周第一天（周一）
	 * 
	 * @param date
	 * @return
	 * @throws Exception
	 */
	public static Date getLastWeekStart(Date date) {
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		calendar.setTime(date);
		int i = calendar.get(calendar.DAY_OF_WEEK) - 1;
		int startnum = 0;
		if (i == 0) {
			startnum = 7 + 6;
		} else {
			startnum = 7 + i - 1;
		}
		calendar.add(calendar.DATE, -startnum);

		return str2Date(date2Str(calendar.getTime()));
	}

	/**
	 * 返回指定月的最后一天 比如 201002 获取2月的最后一天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int getLastDayOfMonth(int year, int month) {
		Calendar calendar = Calendar.getInstance();

		calendar.set(Calendar.YEAR, year);

		calendar.set(Calendar.MONTH, month);//

		calendar.set(Calendar.DATE, 1);

		calendar.add(Calendar.DATE, -1);

		int end = calendar.get(Calendar.DATE);
		return end;
	}

	/**
	 * 获取上周最后一天（周末）
	 * 
	 * @param date
	 * @return
	 * @throws Exception
	 */
	public static Date getLastWeekEnd(Date date) {
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		calendar.setTime(date);
		int i = calendar.get(calendar.DAY_OF_WEEK) - 1;
		int endnum = 0;
		if (i == 0) {
			endnum = 7;
		} else {
			endnum = i;
		}
		calendar.add(calendar.DATE, -(endnum - 1));

		return str2Date(date2Str(calendar.getTime()));
	}

	/**
	 * 改更现在时间
	 */
	public static Date changeDate(String type, int value) {
		Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
		if (type.equals("month")) {
			calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + value);
		} else if (type.equals("date")) {
			calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + value);
		}
		return calendar.getTime();
	}

	/**
	 * 更改时间
	 */
	public static Date changeDate(Date date, String type, int value) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		if (type.equals("month")) {
			calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + value);
		} else if (type.equals("date")) {
			calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + value);
		} else if (type.endsWith("year")) {
			calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + value);
		}
		return calendar.getTime();
	}

	/**
	 * 比较时间是否在这两个时间点之间
	 * 
	 * @param time1
	 * @param time2
	 * @return
	 */
	public static boolean checkTime(String time1, String time2) {
		Calendar calendar = Calendar.getInstance();
		Date date1 = calendar.getTime();
		Date date11 = DateUtil.str2Date(DateUtil.date2Str(date1, "yyyy-MM-dd")
				+ " " + time1);// 起始时间

		Calendar c = Calendar.getInstance();
		c.add(Calendar.DATE, 1);
		Date date2 = c.getTime();
		Date date22 = DateUtil.str2Date(DateUtil.date2Str(date2, "yyyy-MM-dd")
				+ " " + time2);// 终止时间

		Calendar scalendar = Calendar.getInstance();
		scalendar.setTime(date11);// 起始时间

		Calendar ecalendar = Calendar.getInstance();
		ecalendar.setTime(date22);// 终止时间

		Calendar calendarnow = Calendar.getInstance();

		if (calendarnow.after(scalendar) && calendarnow.before(ecalendar)) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 检查输入日期是否是interval月之内的日期
	 * 
	 * @param time
	 * @param interval
	 * @return
	 */
	public static boolean checkOnly6Month(String time, int interval) {
		boolean t = true;
		Calendar calendarnow = Calendar.getInstance();
		Date datetmp = DateUtil.str2Date(time + " 00:00:01");
		Calendar scalendar = Calendar.getInstance();
		scalendar.setTime(datetmp);// 要判断的时间点
		calendarnow.add(Calendar.MONTH, interval); // 将当前日期前翻interval个月
		calendarnow.set(Calendar.DAY_OF_MONTH, 1);// 将当前日期前翻interval个月之后
		// 将日期翻到该月第一天
		calendarnow.set(Calendar.HOUR_OF_DAY, 0);
		calendarnow.set(Calendar.MINUTE, 0);
		calendarnow.set(Calendar.SECOND, 0);

		if (!scalendar.after(calendarnow)) {
			t = false;
		}
		return t;
	}

	/**
	 * 计算两个日期相隔的天数
	 * 
	 * @param firstString
	 * @param secondString
	 * @return
	 */
	public static int nDaysBetweenTwoDate(String starttime, String endtime) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date firstDate = null;
		Date secondDate = null;
		try {
			firstDate = df.parse(starttime);
			secondDate = df.parse(endtime);
			int nDay = (int) ((secondDate.getTime() - firstDate.getTime()) / (24 * 60 * 60 * 1000));
			return nDay;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("日期格式错误");
		}
		
	}

	/**
	 * 从日期中获取年或月或日单个的数值，如2012-1-22获取年的值是2012，获取月的值是1，获取日的值是22
	 * 
	 * @param date
	 * @param format
	 * @return
	 */
	public static Integer getIntFromDate(Date date, String format) {
		if (date == null) {
			return null;
		}

		Integer y = null;
		String year = date2Str(date, format);
		if (StringUtils.isNotEmpty(year)) {
			try {
				y = Integer.valueOf(year);
			} catch (Exception e) {
				log.error("string to int error. year=" + year + e.getMessage(),
						e);
				return null;
			}
		}
		return y;
	}

	/**
	 * 获取当月第一天和下月第一天
	 * 
	 * @return
	 */
	public static List<Date> getFirstAndLastDayOfMonth() {
		List<Date> listDate = new ArrayList<Date>();
		// 获取当前日期 并设置0时0分0秒
		Calendar cal_now = Calendar.getInstance();
		cal_now.set(Calendar.HOUR_OF_DAY, 0);
		cal_now.set(Calendar.MINUTE, 0);
		cal_now.set(Calendar.SECOND, 0);
		// 设置为1号,当前日期既为本月第一天
		cal_now.set(Calendar.DAY_OF_MONTH, 1);
		listDate.add(cal_now.getTime());
		// 设置为下月1号
		cal_now.add(Calendar.MONTH, 1);
		listDate.add(cal_now.getTime());
		return listDate;
	}

	/**
	 * 获取今天和昨天开始时间
	 * 
	 * @return
	 */
	public static List<Date> getLastDayAndToday() {
		List<Date> listDate = new ArrayList<Date>();
		// 获取当前日期 并设置0时0分0秒
		Calendar cal_now = Calendar.getInstance();
		cal_now.set(Calendar.HOUR_OF_DAY, 0);
		cal_now.set(Calendar.MINUTE, 0);
		cal_now.set(Calendar.SECOND, 0);
		listDate.add(cal_now.getTime());
		// 设置到昨天
		cal_now.add(Calendar.DATE, -1);
		listDate.add(cal_now.getTime());
		return listDate;
	}

	/**
	 * 获取今天和明天开始时间
	 * 
	 * @return
	 */
	public static List<Date> getCurDayAndTomorrowDay() {
		List<Date> listDate = new ArrayList<Date>();
		// 获取当前日期 并设置0时0分0秒
		Calendar cal_now = Calendar.getInstance();
		cal_now.set(Calendar.HOUR_OF_DAY, 0);
		cal_now.set(Calendar.MINUTE, 0);
		cal_now.set(Calendar.SECOND, 0);
		listDate.add(cal_now.getTime());
		// 设置第二天
		cal_now.add(Calendar.DAY_OF_MONTH, 1);
		listDate.add(cal_now.getTime());
		return listDate;
	}

	/**
	 * 获取当前时间小时和下个小时
	 * 
	 * @return
	 */
	public static List<Date> getCurHourAndNextHour() {
		List<Date> listDate = new ArrayList<Date>();
		// 获取当前小时并设置0分0秒
		Calendar cal_now = Calendar.getInstance();
		cal_now.set(Calendar.MINUTE, 0);
		cal_now.set(Calendar.SECOND, 0);
		listDate.add(cal_now.getTime());
		// 设置下个小时
		cal_now.add(Calendar.HOUR_OF_DAY, 1);
		listDate.add(cal_now.getTime());
		return listDate;
	}

	/**
	 * 获取当前时间距离结束时间毫秒数
	 * 
	 * @param toDate
	 * @return
	 */
	public static long getNowInteval(Date toDate) {
		return toDate.getTime() - System.currentTimeMillis();
	}

	/**
	 * 比较当前时间是否比原时间最多相差一分钟
	 * 
	 * @param d
	 *            原时间
	 * @return
	 */
	public static boolean checkOneMinute(Date d) {
		boolean b = false;
		long num = System.currentTimeMillis() - d.getTime();
		if (num <= 60000)
			b = true;
		return b;
	}

	/**
	 * 比较当前时间和原时间是否在同一天
	 * 
	 * @param d
	 * @return
	 */
	public static boolean isTheSameDay(Date d) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(d);
		c2.setTime(new Date());
		return (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR))
				&& (c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH))
				&& (c1.get(Calendar.DAY_OF_MONTH) == c2
						.get(Calendar.DAY_OF_MONTH));
	}

	/**
	 * 判断当前时候是否是忙时 是返回true  反之 false ||请求时间与2取摸 整出的返回true 反之false
	 * @return
	 */
	public static boolean checkHotTime() {
		boolean b = false;
//		Calendar ca = Calendar.getInstance();
//		int hour = ca.get(Calendar.HOUR);// 小时
//		if ((hour >= 8 && hour <= 11) || (hour >= 13 && hour <= 18)) {
//			b = true;
//		}
		Long s = System.currentTimeMillis();
		if(s%2==0){
			b = true;
		}
		return b;
	}

	
	public static String getCurrentDate(String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(new Date());
	}
	
	public static String getYesterday(String format) {
		Calendar cal_now = Calendar.getInstance();
		// 设置到昨天
		cal_now.add(Calendar.DATE, -1);
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(cal_now.getTime());
	}
	
	/**
	 * 计算n天前的日期
	 * @param format
	 * @param n  当n为正数时，计算n天前日期，当n为负数时，计算n天数的日期
	 * @return
	 */
	public static String getAday(String format, int n) {
		Calendar cal_now = Calendar.getInstance();
		// 设置到昨天
		cal_now.add(Calendar.DATE, -n);
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(cal_now.getTime());
	}
	
	
	/**
	 * 计算n天前的日期
	 * @param format
	 * @param n  当n为正数时，计算n天前日期，当n为负数时，计算n天数的日期
	 * @return
	 */
	public static long getAday_Long(int n) {
		Calendar cal_now = Calendar.getInstance();
		// 设置到昨天
		cal_now.set(Calendar.DATE, cal_now.get(Calendar.DATE)+n);  
		Date date = cal_now.getTime();
		return date.getTime();
	}
	
	public static boolean between (Date begin, Date end, Date cur) {
	  if(cur.after(begin) && cur.before(end)) {
	    return true;
	  }
	  return false;
	}
	
	
//	public static void main(String[] args) {
//		
//		Date dta = new Date(System.currentTimeMillis());
//		for ( int i=0; i<21; i++ ){
//			String str = DateUtil.date2StrByEnum(dta, DateUtil.DateTimeFormat.values()[i]);
//			//System.out.println(str);
//		}
//		
//		for ( int i=0; i<10; i++ ){
//			String str = DateUtil.date2TimeStrByEnum(dta, DateUtil.TimeFormat.values()[i]);
//			System.out.println(str);
//		}
//		
//	
////	  
////		Date d = new Date();
////		Integer year = getIntFromDate(d, "yyyy");
////		Integer month = getIntFromDate(d, "MM");
////		Integer date = getIntFromDate(d, "dd");
////		// DateUtil dateUtil = new DateUtil();
////
////		List<Date> listDate = DateUtil.getFirstAndLastDayOfMonth();
////		for (Date date1 : listDate)
////			System.out.println(DateUtil.date2Str(date1));
////
////		List<Date> listDate2 = DateUtil.getCurDayAndTomorrowDay();
////		for (Date date2 : listDate2)
////			System.out.println(DateUtil.date2Str(date2));
////
////		List<Date> listDate3 = DateUtil.getCurHourAndNextHour();
////		for (Date date3 : listDate3)
////			System.out.println(DateUtil.date2Str(date3));
////		
//		//"yyyy-MM-dd HH:mm:ss";
//		String begin1 = "00:00";
//		String end1 = "00:00";
//		String cur = "7:00";
//		
//		boolean ls = DateUtil.between(DateUtil.str2Date(begin1, "HH:mm"), DateUtil.str2Date(end1, "HH:mm"), DateUtil.str2Date(cur, "HH:mm"));
//		System.out.println(ls);
//		
////		 Date begintime = DateUtil.str2Date(begin, "HH:mm");
////     Date endtime = DateUtil.str2Date(end, "HH:mm");
////     
////     System.out.println(begintime.after(endtime));
////     
//		
//		// List<String> list = new ArrayList<String>();
//		// System.out.println(list.isEmpty());
//		
//		 Calendar ca = Calendar.getInstance();
//     int hh = ca.get(Calendar.HOUR_OF_DAY);
//     int mins = ca.get(Calendar.MINUTE);
//     // Date curentDate = DateUtil.str2Date(hh + ":" + mins, "HH:mm");
//     Date curentDate = DateUtil.str2Date("24:00", "HH:mm");
//     System.out.println(curentDate);
//     
//     
//    
//       try{
//         Date begin = DateUtil.str2Date(begin1, "HH:mm");
//         Date end = DateUtil.str2Date(end1, "HH:mm");
//         if(begin.after(end)){
//           System.out.println("after");
//         } else {
//           System.out.println("before");
//         }
//       }catch(Exception ex){
//         
//       }
//		
//	}

}
